package pishen;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import edu.uci.ics.jung.graph.Graph;
import edu.uci.ics.jung.graph.SparseGraph;
import edu.uci.ics.jung.graph.util.EdgeType;

public class BlockModelA {
	private Graph<Node, Edge> graph;
	private String model;
	private ArrayList<Node> infectedList;
	private ArrayList<Node> blockedList;
	private ArrayList<Node>[] blockedLists;
	// p => proportion of blocking neighbor of infected nodes 
	// 1-p => proportion of blocking other high degree nodes in whole graph 
	private double p = 1.0 ; 
	
	public BlockModelA(Graph<Node, Edge> graph, List<Node> sourceList, String model){
		this.graph = graph;
		this.model = model;
		this.infectedList = (ArrayList<Node>)sourceList;
		this.blockedList = new ArrayList<Node>();
		this.blockedLists = (ArrayList<Node>[])new ArrayList[6];
	}
	
	public void run(){
		List<Node> infectedNeighborList = new ArrayList<Node>();
		// find neighbor of infected nodes
		for (Node v : infectedList){
			for(Node n : graph.getSuccessors(v)){
				if(!infectedList.contains(n) && !infectedNeighborList.contains(n)){
					infectedNeighborList.add(n);
				}
			}
		}		
		
		int maxCount = graph.getVertexCount(); 
		
		System.out.println("blocking neighbor rate=" + p);
		
		int level = 0;
		// record blocking rate (from 0 , 0.01 , 0.02 , 0.03 , 0.04 , 0.05)
		for(double blockPercent = 0.00 ; blockPercent<=0.05 ; blockPercent+= 0.01){
			System.out.println("blockPercent=" + blockPercent);
			// blocking neighbor of infected nodes s 
			System.out.println("blocking neighbor of infected nodes s");
			while(graph.getVertexCount() > (1- blockPercent * p) * maxCount){
				System.out.print(".");
				Node maxDegreeNode = null;
				for(Node nodeOnList : infectedNeighborList){				
					if(maxDegreeNode == null || graph.getNeighborCount(nodeOnList) >= graph.getNeighborCount(maxDegreeNode))
						maxDegreeNode = nodeOnList;
				}
				blockedList.add(maxDegreeNode);
				graph.removeVertex(maxDegreeNode);
				infectedNeighborList.remove(maxDegreeNode);
				maxDegreeNode = null;
			}
			System.out.println();
		
			// blocking remain high degree nodes in whole graph 
			System.out.println("blocking remain high degree nodes in whole graph");
			while(graph.getVertexCount() > (1- blockPercent) * maxCount){
				System.out.print(".");
				Node maxDegreeNode = null;
				for(Node n : graph.getVertices()){
					if(!infectedList.contains(n) && !infectedNeighborList.contains(n)){
						if(maxDegreeNode == null || graph.getNeighborCount(n) >= graph.getNeighborCount(maxDegreeNode))
							maxDegreeNode = n;
					}
				}
				blockedList.add(maxDegreeNode);
				graph.removeVertex(maxDegreeNode);
				maxDegreeNode = null;
			}
			System.out.println();
			
			blockedLists[level] = (ArrayList<Node>)(blockedList.clone());
			level++;
		}
	}
	
	
	public List<Node>[] getBlockedLists(){
		return blockedLists;
	}
	
}